package com.ithuameng.admin.config;

import com.ithuameng.admin.interceptor.JwtAuthenticationFilter;
import com.ithuameng.admin.security.CustomAccessDeniedHandler;
import com.ithuameng.admin.security.CustomAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;

/**
 * Spring Security 配置
 *
 * @author ithuameng
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
class SecurityConfig {

    private static final String[] SWAGGER_URI = {
            "/swagger-ui/**",
            "/webjars/**",
            "/v2/**",
            "/v3/**",
            "/swagger-resources/**"
    };

    private static final String[] PUBLIC_URI = {
            "/admin/v1/account/logout",
            "/admin/v1/account/login",
            "/admin/v1/common/error/**"
    };

    @Resource
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Resource
    @Qualifier("adminUserDetailService")
    private UserDetailsService adminUserDetailService;

    @Order(1)
    @Configuration
    class AdminSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(WebSecurity web) {
            web.ignoring().antMatchers(SWAGGER_URI);
        }

        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            http.cors().and().antMatcher("/admin/**").httpBasic().disable().csrf().disable().sessionManagement()
                    .sessionCreationPolicy(STATELESS).and().authorizeRequests().antMatchers(PUBLIC_URI).permitAll()
                    .anyRequest().authenticated().and().exceptionHandling()
                    .accessDeniedHandler(new CustomAccessDeniedHandler()).and().exceptionHandling()
                    .authenticationEntryPoint(new CustomAuthenticationEntryPoint()).and().addFilterBefore(
                    jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(adminUserDetailService);
        }
    }
}